package pers.vic.upload.business.service.impl;

import cn.xuqiudong.common.base.model.BaseResponse;
import cn.xuqiudong.common.base.tool.Tools;
import org.springframework.stereotype.Service;
import pers.vic.upload.business.model.AssertModel;
import pers.vic.upload.business.model.InsuranceModel;
import pers.vic.upload.business.service.BaseBusinessService;
import pers.vic.upload.constant.FileType;
import pers.vic.upload.constant.FinalFiledParams;
import pers.vic.upload.constant.ResultEnum;
import pers.vic.upload.login.model.User;
import pers.vic.upload.utils.SessionHelper;

import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 描述:保险业务处理
 * @author Vic.xu
 * @date 2022-07-22 10:09
 */
@Service
public class InsuranceServiceImpl extends BaseBusinessService<InsuranceModel> {
    /**
     * FILENAME_FRAGMENT  9 → 4
     */
    private static final int FILENAME_FRAGMENT = 4;

    /*
    校验文件名称的:
    识别方法+识别号+保险类型+保险公司/保赔协会+保险额/油污限额+
    币种+起始日期+截止日期+被保险人或受益人是否为我司或我司sp
     */
    /*
      ICBCSTL-68545
      命名规则： 修改了
      识别号_保险类型（对应英文）_起始日期-截止日期；   保险
      识别号_证书类型（对应英文）_起始日期-截止日期；   权证
      具体类型对应英文参照01；命名规则参照02
     */

    @Override
    public FileType type() {
        return FileType.insurance;
    }

    @Override
    public BaseResponse<InsuranceModel> check(String fileName, boolean ignoreUnique) {
        Map<Integer, String> map = splitFileName(fileName);
        if (map == null || map.size() != FILENAME_FRAGMENT) {
            return BaseResponse.error("不合法的文件名");
        }
        InsuranceModel model = new InsuranceModel();

        //1 识别号 放在最后
        String identityCode = map.get(1);
        model.setIdentityCode(identityCode);
        AssertModel asset = findAsset(identityCode);
        if ( asset == null) {
            return BaseResponse.error("系统中不存在的识别号:" + identityCode);
        }
        model.setFkAssetId(asset.getId());
        model.setIdentityMethod(asset.getMethod());
        //2保险类型
        String insureType = map.get(2);
        BaseResponse<String>  insureTypeCheck = queryOptionValue(FinalFiledParams.PCODE_MPINSURETYPE, insureType);
        if (!insureTypeCheck.isSuccess()) {
            return BaseResponse.error(insureTypeCheck.getCode(), insureTypeCheck.getMsg());
        }
        model.setInsureType(insureTypeCheck.getData());
        map.put(2, insureTypeCheck.getData());
        //3  起始日期
        String startDateStr = map.get(3);
        if (isNotDate(startDateStr)) {
            return BaseResponse.error("不合法的起始日期");
        }
        Date startDate = toDate(startDateStr);
        model.setStartDate(startDate);
        //4  截至日期
        String endDateStr = map.get(4);
        if (isNotDate(endDateStr)) {
            return BaseResponse.error("不合法的起始日期");
        }
        Date endDate = toDate(endDateStr);
        if (endDate.before(startDate)) {
            return BaseResponse.error("截止日期大于起始日期");
        }
        model.setEndDate(endDate);


        if (!ignoreUnique && existFileNameDataCheck(map)) {
            return BaseResponse.error(ResultEnum.EXISTED_IDENTITY_CODE);
        }

        return BaseResponse.success(model);
    }

    @Override
    protected boolean existFileNameDataCheck(Map<Integer, String> map) {
        String sql = "select  count(1)   " +
                " from  T_MPL_INSURANCE_MANAGE a " +
                " where a.identity_code = ? " +
                " and a.insure_type = ?  " +
                " and to_char(a.start_date, 'YYYYMMDD') = ?" +
                " and to_char(a.end_date, 'YYYYMMDD') = ?";
        Integer num = jdbcTemplate.queryForObject(sql, Integer.class, map.get(1), map.get(2), map.get(3), map.get(4));
        return num != null && num > 0;
    }

    /**
     * 文件名次改了， 所以此check方法不再使用了
     * @see #check(String, boolean) 
     */
    @Deprecated
    public BaseResponse<InsuranceModel> oldCheck(String fileName, boolean ignoreUnique) {
        Map<Integer, String> map = splitFileName(fileName);
        if (map == null || map.size() != FILENAME_FRAGMENT) {
            return BaseResponse.error("不合法的文件名");
        }
        InsuranceModel model = new InsuranceModel();
        // 1 识别方法
        String identityMethod = map.get(1);
        BaseResponse<String> identityMethodCheck = queryOptionValue(FinalFiledParams.PCODE_IDENTIFYMETHODMP, identityMethod);
        if (!identityMethodCheck.isSuccess()) {
            return BaseResponse.error(identityMethodCheck.getCode(), identityMethodCheck.getMsg());
        }
        model.setIdentityMethod(identityMethodCheck.getData());
        //CHECK 2 识别号
        String identityCode = map.get(2);
        if (!ignoreUnique && identityCodeCheck(identityCode)) {
            return BaseResponse.error(ResultEnum.EXISTED_IDENTITY_CODE);
        }
        model.setIdentityCode(identityCode);
        // CHECK 3 保险类型
        String insureType = map.get(3);
        BaseResponse<String>  insureTypeCheck = queryOptionValue(FinalFiledParams.PCODE_MPINSURETYPE, insureType);
        if (!insureTypeCheck.isSuccess()) {
            return BaseResponse.error(insureTypeCheck.getCode(), insureTypeCheck.getMsg());
        }
        model.setInsureType(insureTypeCheck.getData());
        // 4 保险公司
        String insureCompany = map.get(4);
        model.setInsureCompany(insureCompany);
        //5  保险额
        String insureMoney = map.get(5);
        model.setInsureMoney(insureMoney);
        //6 币种
        String currency = map.get(6);
        BaseResponse<String> currencyCheck = queryOptionValue(FinalFiledParams.PCODE_CURRENCY, currency);
        if (!currencyCheck.isSuccess()) {
            return BaseResponse.error(currencyCheck.getCode(), currencyCheck.getMsg());
        }
        model.setCurrency(currencyCheck.getData());

        //7  起始日期
        String startDateStr = map.get(7);
        if (isNotDate(startDateStr)) {
            return BaseResponse.error("不合法的起始日期");
        }
        Date startDate = toDate(startDateStr);
        model.setStartDate(startDate);
        //8  截至日期
        String endDateStr = map.get(8);
        if (isNotDate(endDateStr)) {
            return BaseResponse.error("不合法的起始日期");
        }
        Date endDate = toDate(endDateStr);
        if (endDate.before(startDate)) {
            return BaseResponse.error("截至日期大于起始日期");
        }
        model.setEndDate(endDate);
        //9 被保险人或受益人是否为我司或我司sp
        String myOrNot = map.get(9);
        BaseResponse<String> myOrNotCheck = queryOptionValue(FinalFiledParams.PCODE_ISORNOT, currency);
        if (!myOrNotCheck.isSuccess()) {
            return BaseResponse.error(myOrNotCheck.getCode(), myOrNotCheck.getMsg());
        }
        model.setMyOrNot(myOrNotCheck.getData());
        return BaseResponse.success(model);
    }

    @Override
    public String save(InsuranceModel model) {
        String userId = SessionHelper.userId();
        String id = Tools.randomUuid();
        User user = SessionHelper.getSocketThreadUserWithoutNull();
        model.setId(id);
        String sql = "insert into T_MPL_INSURANCE_MANAGE" +
                "(ID, CREATE_DATE, Create_User_Id, ENABLE_FLAG, LAST_UPDATE_DATE, LAST_UPDATE_USER_ID, " +
                " Identity_Code, Insure_Type,Start_Date, End_Date, IDENTITY_METHOD, " +
                " Status,fk_asset_id, fk_organization_id, fk_legal_organization_id, FK_OWNER_ID) " +
                " values(?, sysdate, ?, 1, sysdate, ?," +
                " ?,?, ?,?, ?," +
                " ?, ?, ?, ?, ?)";
        Object[] params = {id, userId, userId, model.getIdentityCode(),
                model.getInsureType(),
                model.getStartDate(), model.getEndDate(),model.getIdentityMethod(),
                STATUS, model.getFkAssetId(), user.getFkOrganizationId(), user.getFkOrgCompanyId(), userId};
        jdbcTemplate.update(sql, params);
        return id;
    }

    @Override
    public void saveRelation(String id, String attachmentId) {
        attachmentService.insertRelation("T_MPL_INSURANCE_attach","FK_INSURANCE_ID", id, "FK_ATTACH_ID", attachmentId);
    }

    @Override
    public boolean identityCodeCheck(String identityCode) {
        String sql = "select count(1) from  T_MPL_INSURANCE_MANAGE a where a.identity_code = ?";
        Integer num = jdbcTemplate.queryForObject(sql, Integer.class, identityCode);
        return num != null && num > 0;
    }

    @Override
    public List<Map<String, Object>> find() {

        String sql = "select c.file_name,c.original_file_name,c.file_path, a.* " +
                "from T_MPL_INSURANCE_MANAGE a  " +
                "left join  T_MPL_INSURANCE_attach b on a.id = b.fk_insurance_id " +
                "left join   T_STL_S_ATTACHMENT c on c.id =b.fk_attach_id " +
                "where 1=1  order by a.create_date desc ";

        sql = MessageFormat.format("select * from ({0} ) where rownum < 11", sql);
        return jdbcTemplate.queryForList(sql);
    }

}
